package com.sinai.mshab.client.pages;

import java.util.ArrayList;

import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.KeyboardListener;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.sinai.mshab.client.formatting.Direction;
import com.sinai.mshab.client.formatting.LazyLoaded;
import com.sinai.mshab.client.util.Observable;
import com.sinai.mshab.client.util.Observer;
import com.sinai.mshab.client.widgets.FormatPanel;
import com.sinai.mshab.client.widgets.NotifyPanel;

/**
 * Generic login page. Takes in a title, instructions and an observer who will
 * be notified when the user attempts to login.
 * 
 * @author serge
 */
public class LoginPage extends VerticalPanel implements Observable {

	private TextBox username;
	private PasswordTextBox password;
	private FormatPanel aboveLoginPanel, belowLoginPanel;
	private NotifyPanel login_failed;
	private ArrayList<Observer> observers = new ArrayList<Observer>();
	private String heading, instructions;

	public LoginPage(String heading, String instructions, Observer ob) {

		// set up the page
		setStyleName("mshab-Page");
		addObserver(ob);

		// set up the main page panel
		FormatPanel panel = new FormatPanel();

		// adding login heading
		Label login_label = new Label(heading);
		login_label.setStyleName("h2");
		panel.add(login_label);

		// adding login instructions
		Label instructions_label = new Label(instructions);
		instructions_label.setStyleName("mshab-DescrptionLabel");
		panel.add(instructions_label);

		// set up the above logging panel
		aboveLoginPanel = new FormatPanel();
		panel.add(aboveLoginPanel);
		aboveLoginPanel.setVisible(false);

		// set up the actual login panel
		FormatPanel login_panel = new FormatPanel();
		login_panel.setDefaultLabelPosition(Direction.LEFT);
		login_panel.setDefaultLeftLabelWidth(80);
		login_panel.setStyleName("mshab-LoginPanel");

		// adding username
		username = new TextBox();
		login_panel.add(username);
		login_panel.setLabel(username, "Username:");

		// adding password
		password = new PasswordTextBox();
		login_panel.add(password);
		login_panel.setLabel(password, "Password:");
		password.addKeyboardListener(new LoginListener());

		// create login failed notification
		login_failed = new NotifyPanel("Login Failed");
		login_failed.setVisible(false);
		login_panel.add(login_failed);

		// adding submit button
		Button login_button = new Button("Login");
		login_button.addClickListener(new LoginListener());
		login_button.setStyleName("mshab-LoginButton");
		login_panel.add(login_button);

		// set up the below logging panel
		belowLoginPanel = new FormatPanel();
		panel.add(belowLoginPanel);
		belowLoginPanel.setVisible(false);

		panel.add(login_panel);
		add(panel);
	}

	/**
	 * Fails the login form with a default message.
	 */
	public void fail() {
		login_failed.setVisible(true);
	}

	/**
	 * Fails the login form with a custom message
	 * 
	 * @param message
	 *            the message to display in the notifier
	 */
	public void fail(String message) {
		login_failed.setText(message);
		login_failed.setVisible(true);
	}

	/**
	 * Add an element to the panel above the login boxes
	 * 
	 * @param w
	 *            the element to add.
	 */
	public void addAbove(Widget w) {
		belowLoginPanel.setVisible(true);
		aboveLoginPanel.add(w);
	}

	/**
	 * Add element to the panel below the login boxes.
	 * 
	 * @param w
	 *            the element to add.
	 */
	public void addBelow(Widget w) {
		belowLoginPanel.setVisible(true);
		belowLoginPanel.add(w);
	}

	/**
	 * @return the username
	 */
	public String getUsername() {
		return null;
	}

	/**
	 * @return the password
	 */
	public String getPassword() {
		return null;
	}

	/**
	 * 
	 * @author serge
	 * 
	 */
	private class LoginListener implements ClickListener, KeyboardListener {
		public void onClick(Widget sender) {
			notifyObservers();
		}

		public void onKeyDown(Widget sender, char keyCode, int modifiers) {

			// someone hit enter
			if ((int) keyCode == 13) {
				notifyObservers();
			}
		}

		public void onKeyPress(Widget sender, char keyCode, int modifiers) {
			// TODO Auto-generated method stub
		}

		public void onKeyUp(Widget sender, char keyCode, int modifiers) {
			// TODO Auto-generated method stub
		}
	}

	public void addObserver(Observer o) {
		observers.add(o);
	}

	public void notifyObservers() {
		for (int i = 0; i < observers.size(); i++) {
			observers.get(i).update(this, "login");
		}
	}
}
